package nl.nhl.idp.Components.Database;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Handles database access for IDP
 * @author Mark van der Wal
 *
 */
public class DatabaseHelper extends SQLiteOpenHelper 
{
	// constants
	public static final String DATABASE_NAME = "SensorDataDB";
	private static final int DATABASE_VERSION = 1;
	
	private static final String TABLE_SESSIONS = "Sessions";
	private static final String TABLE_SENSORDATA = "SensorData";
	
	private static final String COLUMN_ID_SESSIONS = "session_id";
	private static final String COLUMN_ID_SENSORDATA = "sensordata_id";
	
	private static final String DATABASE_CREATE_SESSIONS = "CREATE TABLE " 
			+ TABLE_SESSIONS + " (" 
			+ COLUMN_ID_SESSIONS 
			+ " INTEGER PRIMARY KEY AUTOINCREMENT, startTime INTEGER, endTime INTEGER);";
	
	private static final String DATABASE_CREATE_SENSORDATA = "CREATE TABLE "
			+ TABLE_SENSORDATA + " ("
			+ COLUMN_ID_SENSORDATA
			+ " INTEGER PRIMARY KEY AUTOINCREMENT, sessionID INTEGER,hellingshoek INTEGER, motorspanning INTEGER, motorStroom INTEGER, accuspanning INTEGER," 
			+ " mazeLeft INTEGER, mazeForward INTEGER, mazeRight INTEGER);";
	
	/**
	 * Constructor
	 * @param context this database is used in
	 */
	public DatabaseHelper(Context context)
	{
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) 
	{
		// create the database if it does not exist
		db.execSQL(DATABASE_CREATE_SESSIONS);
		db.execSQL(DATABASE_CREATE_SENSORDATA);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
	{
		// delete old and create new
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_SESSIONS);
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_SENSORDATA);
		
		// create new database
		onCreate(db);
	}
	
	/**
	 * Create a new sesion in the database
	 * @return returns the session
	 */
	public Session CreateSession()
	{
	   SQLiteDatabase db = this.getWritableDatabase();
	   ContentValues cv = new ContentValues();
	   Session session = new Session();
	   
	   // get current time
	   long start = (new Date()).getTime();
	   
	   // inserting row
	   cv.put("startTime", start);
	   int id = (int) db.insert(TABLE_SESSIONS, null, cv);
	   db.close();
	   
	   if(id == -1)
		   return null;
	   
	   session.setID(id);
	   session.setStartTime(start);
	   return session;
	}
	
	/**
	 * Add sensor data to a given session
	 * @param session to add the sensordata to
	 * @param data the data to add
	 * @return true if succeeded , false if not succeeded
	 */
	public SensorData AddSensorData(Session session, SensorData data)
	{
		if(session.getID() == 0)
			return null;
		
		SensorData sData = new SensorData();
		int id = 0;
		
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues cv = new ContentValues();
		
		cv.put("sessionID", session.getID());
		cv.put("hellingshoek", data.getHellingshoek());
		cv.put("motorspanning", data.getMotorspanning());
		cv.put("motorStroom", data.getMotorstroom());
		cv.put("accuspanning", data.getAccuspanning());
		cv.put("mazeLeft", data.getMazeSensorLeft());
		cv.put("mazeForward", data.getMazeSensorForward());
		cv.put("mazeRight", data.getMazeSensorRight());
		
		if( (id = (int)db.insert(TABLE_SENSORDATA, null, cv)) == -1)
		{
			db.close();
			return null;
		}
		
		// fill data
		sData.setID(id);
		sData.setHellingshoek(data.getHellingshoek());
		sData.setMotorspanning(data.getMotorspanning());
		sData.setMotorstroom(data.getMotorstroom());
		sData.setAccuspanning(data.getAccuspanning());
		sData.setMazeSensors(data.getMazeSensorLeft(), 
				data.getMazeSensorForward(),
				data.getMazeSensorRight());
		
		db.close();
		return sData;
	}
	
	/**
	 * Get all sessions available
	 * @return list of sessions
	 */
	public List<Session> GetSessions()
	{
		List<Session> sessions = new ArrayList<Session>();
		String query = "SELECT * FROM " + TABLE_SESSIONS;
		
	    SQLiteDatabase db = this.getReadableDatabase();
	    Cursor cursor = db.rawQuery(query, null);
	    
	    if(cursor.getCount() <= 0)
	    {
	    	db.close();
	    	return null;
	    }
	 
	    // loop through all the rows and add to the list
	    if (cursor.moveToFirst()) 
	    {
	        do
	        {
	            Session session = new Session();
	            session.setID(cursor.getInt(0));
	            session.setStartTime(cursor.getLong(1));
	            session.setEndTime(cursor.getLong(2));
	            
	            // Adding sessions to the list
	            sessions.add(session);
	        } 
	        while ( cursor.moveToNext() );
	    }
		
	    db.close();
		return sessions;
	}
	
	/**
	 * Update the session with the endtime
	 * @param time
	 */
	public void SetSessionEndTime(Session session)
	{
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues cv = new ContentValues();
		
		cv.put("endTime", session.getEndTimeLong());
		db.update(TABLE_SESSIONS, cv, COLUMN_ID_SESSIONS + "=" + session.getID(), null);

		db.close();
	}
	
	/**
	 * Gets a list of sensordata that belongs to the given session
	 * @param session id which we want to get the sensordata from
	 * @return list of sensordata
	 */
	public List<SensorData> GetSensorData(Session session)
	{
		if(session.getID() == 0)
			return null;
		
		List<SensorData> sensorData = new ArrayList<SensorData>();
		String query = "SELECT * FROM " + TABLE_SENSORDATA + " WHERE sessionID=" + session.getID();
		
	    SQLiteDatabase db = this.getReadableDatabase();
	    Cursor cursor = db.rawQuery(query, null);
	    
	    if(cursor.getCount() <= 0)
	    {
	    	db.close();
	    	return null;
	    }
	 
	    // loop through all the rows and add to the list
	    if (cursor.moveToFirst()) 
	    {
	        do
	        {
	        	SensorData sData = new SensorData();
	        	
	        	sData.setID(cursor.getInt(0));
	        	sData.setSessionId(cursor.getInt(1));
	        	sData.setHellingshoek(Integer.parseInt(cursor.getString(2)));
	        	sData.setMotorspanning(Integer.parseInt(cursor.getString(3)));
	        	sData.setMotorstroom(Integer.parseInt(cursor.getString(4)));
	        	sData.setAccuspanning(Integer.parseInt(cursor.getString(5)));
	        	sData.setMazeSensors(Short.parseShort(cursor.getString(6)), 
					        			Short.parseShort(cursor.getString(7)), 
					        			Short.parseShort(cursor.getString(8)));
	        	
	            // Adding sensor data to the list
	            sensorData.add(sData);
	        } 
	        while ( cursor.moveToNext() );
	    }
		
	    db.close();
		return sensorData;
	}
	
	/**
	 * Clears the database tables from all data
	 */
	public void ClearDB(Context context)
	{
		context.deleteDatabase(DATABASE_NAME);
	}
}
